home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-03-25 | 48.2 KB | 1,971 lines |
- Newsgroups: comp.sources.misc
- keywords: DOS, floppy
- subject: v11i082: Fast mtools, + mkdfs for SparcStation1 or Sun-3/80 Part 2
- from: viktor@melon.princeton.edu (Viktor Dukhovni)
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 11, Issue 82
- Submitted-by: viktor@melon.princeton.edu (Viktor Dukhovni)
- Archive-name: sparc-mtools/part02
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 3)."
- # Contents: Readme init.c mdir.c mkdfs.c mmd.c mrd.c mread.c mren.c
- # mtype.c subdir.c
- # Wrapped by viktor@cucumber on Fri Mar 16 20:50:08 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Readme' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Readme'\"
- else
- echo shar: Extracting \"'Readme'\" \(3809 characters\)
- sed "s/^X//" >'Readme' <<'END_OF_FILE'
- X MTOOLS
- X version 1.6.2 - 5 Jul 89
- X
- XThis is a collection of MSDOS tools to allow you to read and write to
- XMSDOS formatted diskettes from a Unix based system.
- X
- XThe following MSDOS commands are emulated:
- X
- XMtool MSDOS
- Xname equivalent Description
- X----- ---- -----------
- Xmcopy COPY copy MSDOS files to/from Unix
- Xmdel DEL/ERASE delete a MSDOS file
- Xmdir DIR display a MSDOS directory
- Xmkdfs FORMAT Format and build s DOS file system.
- Xmmd MD/MKDIR make a MSDOS sub directory
- Xmrd RD/RMDIR remove a MSDOS sub directory
- Xmread COPY low level read (copy) a MSDOS file to Unix
- Xmren REN/RENAME rename an existing MSDOS file
- Xmtype TYPE display contents of a MSDOS file
- Xmwrite COPY low level write (copy) a Unix file to MSDOS
- X* CD change working directory
- X
- X * by use of the environmental variable MCWD
- X
- XThe formats of IBM PC floppy disk drives are:
- X
- X bytes per sectors per tracks number total disk introduced
- X sector track per side of sides capacity size in MSDOS
- X 512 8 40 1 160k 5.25 1.0
- X 512 9 40 1 180k 5.25 1.1
- X 512 8 40 2 320k 5.25 2.0
- X 512 9 40 2 360k 5.25 2.0
- X 512 15 80 2 1.2M 5.25 3.0
- X 512 9 80 2 720k 3.5 3.1
- X 512 18 80 2 1.4M 3.5 3.2
- X
- X
- XFind UNIX device(s) capable of reading one or more of these formats
- Xand edit "devices.c" to add them to the driver switch, you may
- Xadd the same device more than once if it supports multiple formats
- Xand needs "ioctls" to be set to the right physical parameters.
- X
- XThe disk geometry can be kept in the environment for unusual cases,
- Xinit.c will pass "NCYL", "NSECT" and "NTRACK" to the disk parameter
- Xsetting routine (if any). This should be documented in an "mtools"
- Xmanual page giving an overview of the whole package, this file is a
- Xstart.
- X
- XThe manuals are very terse... it's assumed that the reader is already
- Xfamiliar with MSDOS.
- X
- XThe use of the environmental variable MCWD to keep track of the current
- Xworking directory is a little awkward, especially since there is no
- X'change directory' command. Bourne shell users will have to type two
- Xcommands to initially set their working directory, ie:
- X
- X MCWD=/TMP
- X export MCWD
- X
- XWildcards are only applied to filenames and not to directory names. For
- Xexample '/usr/local/*.c' is appropriate, but '/usr/l*/main.c' is not.
- X
- XI really wanted to avoid the use of a 'text' mode and a 'data' mode when
- Xtransferring files, but I couldn't find a better way. It gets rather
- Xconfusing and it's quite possible to mess up a file if you apply the
- Xtext mode when it is not appropriate (ie: to a COM or EXE file).
- XLikewise, if you forget to apply the text mode (to a Unix text file)
- Xthen if the file is used under MSDOS, it will be missing carriage
- Xreturns. However, if you aren't going to use the files on your Unix
- Xsystem (you just intend to hold the files and then transfer them back to
- XMSDOS later) then you shouldn't use the text mode during either mread or
- Xmwrite. This is because, the text mode is only useful if the files are
- Xgonna be used under Unix.
- X
- XThe implementation of the Mcopy command is somewhat clumbsy since the
- XMSDOS drive designation "A:" is used. Mcopy is really a front-end to
- Xthe low level Mread and Mwrite commands.
- X
- XThere are is a shell archives called "Unixpc.shar" that contain files
- Xspecific to the AT&T Unix PC 7300/3b1.
- X
- XEmmet P. Gray US Army, HQ III Corps & Fort Hood
- X...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X Directorate of Engineering & Housing
- X Environmental Management Office
- X Fort Hood, TX 76544-5057
- END_OF_FILE
- if test 3809 -ne `wc -c <'Readme'`; then
- echo shar: \"'Readme'\" unpacked with wrong size!
- fi
- # end of 'Readme'
- fi
- if test -f 'init.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'init.c'\"
- else
- echo shar: Extracting \"'init.c'\" \(5152 characters\)
- sed "s/^X//" >'init.c' <<'END_OF_FILE'
- X/*
- X * Initialize a MSDOS diskette. Read the boot block for disk layout
- X * and switch to the proper floppy disk device to match the format
- X * of the disk. Sets a bunch of global variables. Returns 0 on success,
- X * or 1 on failure.
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <signal.h>
- X#include "devices.h"
- X#include "msdos.h"
- X
- X/* #undef DUP_FAT */
- X
- Xextern int fd, dir_len, dir_start, clus_size, fat_len, num_clus;
- Xextern unsigned char *fatbuf;
- Xextern char *mcwd;
- X
- X/* The available drivers */
- Xextern struct device fd_devices[];
- X
- X/* The bootblock */
- Xunion bootblock bb ;
- X
- Xint
- Xinit(mode)
- Xint mode;
- X{
- X int code, buflen, intr();
- X void perror(), exit(), move(), reset_dir();
- X char *getenv(), *fixmcwd(), *malloc(), *dummy;
- X long lseek();
- X struct device *try;
- X int ncyl = 0, nsect = 0, ntrack =0 ;
- X char *floppy = getenv("FLOPPY");
- X
- X /*
- X * Let the user set the geometry in the environment
- X * It is possible for this to be the only way out of the catch-22
- X * wherein the geometry needs to be read from the first block
- X * which cannot be read until the geometry is set!
- X */
- X
- X if ( dummy = getenv("NCYL") )
- X ncyl = strtol(dummy,0,0) ;
- X if ( dummy = getenv("NTRACK") )
- X ntrack = strtol(dummy,0,0) ;
- X if ( dummy = getenv("NSECT") )
- X nsect = strtol(dummy,0,0) ;
- X
- X fd = -1 ;
- X
- X for ( try = fd_devices ; try->drv_dev ; ++try )
- X if ( !floppy ||
- X strncmp(try->drv_dev, floppy, strlen(floppy)) == 0 ) {
- X (void) fprintf(stderr,"\nTrying %s ... ",try->drv_dev) ;
- X fflush(stderr);
- X if ( (fd = open(try->drv_dev, mode|try->drv_mode)) > 0 ) {
- X if ( try->drv_ifunc && (*(try->drv_ifunc))(fd,ncyl,ntrack,nsect) ) {
- X close(fd) ;
- X fd = -1;
- X continue ;
- X }
- X if( read_boot() ) {
- X close(fd) ;
- X fd = -1;
- X continue ;
- X }
- X (void) fprintf(stderr,"ok\n") ;
- X fflush(stderr) ;
- X break ;
- X }
- X perror("open") ;
- X }
- X
- X if ( fd < 0 ) {
- X (void) fprintf(stderr,"All known devices failed.\nSorry.\n") ;
- X exit(1) ;
- X }
- X
- X dir_start = DIROFF(bb.sb) ;
- X dir_len = DIRLEN(bb.sb);
- X clus_size = CLSIZ(bb.sb);
- X fat_len = FATLEN(bb.sb);
- X num_clus = NCLUST(bb.sb);
- X
- X /* Set the parameters if needed */
- X if ( try->drv_ifunc )
- X if( (*(try->drv_ifunc))(fd,NCYL(bb.sb),NTRACK(bb.sb),NSECT(bb.sb)) )
- X exit(1) ;
- X
- X buflen = fat_len * MSECSIZ;
- X fatbuf = (unsigned char *) malloc((unsigned int) buflen);
- X
- X /* read the FAT sectors */
- X move(FATOFF(bb.sb));
- X if (read(fd, fatbuf, buflen) != buflen) {
- X (void) fprintf(stderr,"Could not read the FAT table\n");
- X perror("init: read");
- X exit(1) ;
- X }
- X
- X /* set dir_chain to root directory */
- X reset_dir();
- X /* get Current Working Directory */
- X mcwd = fixmcwd(getenv("MCWD"));
- X /* test it out.. */
- X if (subdir("")) {
- X (void) fprintf(stderr, "Environment variable MCWD needs updating\n");
- X exit(1);
- X }
- X return(0);
- X}
- X
- X/*
- X * Set the logical sector. Non brain-dead drivers don't move the
- X * head until we ask for data, so computing relative seeks is overkill.
- X */
- X
- Xvoid
- Xmove(sector)
- Xint sector;
- X{
- X long lseek();
- X void exit(), perror();
- X
- X if (lseek(fd, (long)sector*MSECSIZ, 0) < 0) {
- X perror("move: lseek");
- X exit(1);
- X }
- X}
- X
- X/*
- X * Fix MCWD to be a proper directory name. Always has a leading separator.
- X * Never has a trailing separator (unless it is the path itself).
- X */
- X
- Xchar *
- Xfixmcwd(dirname)
- Xchar *dirname;
- X{
- X char *s, *ans, *malloc(), *strcpy(), *strcat();
- X
- X if (dirname == NULL)
- X return("/");
- X
- X ans = malloc((unsigned int) strlen(dirname)+2);
- X /* add a leading separator */
- X if (*dirname != '/' && *dirname != '\\') {
- X strcpy(ans, "/");
- X strcat(ans, dirname);
- X }
- X else
- X strcpy(ans, dirname);
- X /* translate to upper case */
- X for (s = ans; *s; ++s) {
- X if (islower(*s))
- X *s = toupper(*s);
- X }
- X /* if separator alone */
- X if (strlen(ans) == 1)
- X return(ans);
- X /* zap the trailing separator */
- X s--;
- X if (*s == '/' || *s == '\\')
- X *s = '\0';
- X return(ans);
- X}
- X
- X/*
- X * Do a graceful exit if the program is interupted. This will reduce
- X * (but not eliminate) the risk of generating a corrupted disk on
- X * a user abort.
- X */
- X
- Xint
- Xintr()
- X{
- X void writefat();
- X
- X writefat();
- X close(fd);
- X exit(1);
- X}
- X
- X/*
- X * Write the FAT table to the disk. Up to now the FAT manipulation has
- X * been done in memory. All errors are fatal. (Might not be too smart
- X * to wait till the end of the program to write the table. Oh well...)
- X */
- X
- Xvoid
- Xwritefat()
- X{
- X int buflen;
- X void move();
- X
- X move(FATOFF(bb.sb)) ;
- X buflen = fat_len * MSECSIZ;
- X if (write(fd, (char *) fatbuf, buflen) != buflen) {
- X perror("writefat: write");
- X exit(1);
- X }
- X#ifdef DUP_FAT
- X /* the duplicate FAT table */
- X if (write(fd, (char *) fatbuf, buflen) != buflen) {
- X perror("writefat: write");
- X exit(1);
- X }
- X#endif /* DUP_FAT */
- X return;
- X}
- X
- Xread_boot()
- X{
- X unsigned char buf[MSECSIZ];
- X static unsigned char ans;
- X
- X move(0) ;
- X
- X if (read(fd, &bb, MSECSIZ) != MSECSIZ ) {
- X return(1) ;
- X }
- X
- X /* Do not know how to deal with non 512 byte blocks! */
- X if ( SECSIZ(bb.sb) != MSECSIZ ) {
- X fprintf(stderr,"File system block size of %d bytes is not valid\n",
- X SECSIZ(bb.sb));
- X exit(1) ;
- X }
- X
- X return(0) ;
- X}
- END_OF_FILE
- if test 5152 -ne `wc -c <'init.c'`; then
- echo shar: \"'init.c'\" unpacked with wrong size!
- fi
- # end of 'init.c'
- fi
- if test -f 'mdir.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mdir.c'\"
- else
- echo shar: Extracting \"'mdir.c'\" \(4882 characters\)
- sed "s/^X//" >'mdir.c' <<'END_OF_FILE'
- X/*
- X * Display a MSDOS directory
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X
- Xint fd; /* the file descriptor for the floppy */
- Xint dir_start; /* starting sector for directory */
- Xint dir_len; /* length of directory (in sectors) */
- Xint dir_entries; /* number of directory entries */
- Xint dir_chain[25]; /* chain of sectors in directory */
- Xint clus_size; /* cluster size (in sectors) */
- Xint fat_len; /* length of FAT table (in sectors) */
- Xint num_clus; /* number of available clusters */
- Xunsigned char *fatbuf; /* the File Allocation Table */
- Xchar *mcwd; /* the current working directory */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int i, entry, files, blocks, fargn, wide, faked;
- X long size;
- X char name[9], ext[4], *date, *time, *convdate(), *convtime();
- X char *strncpy(), newpath[MAX_PATH], *getname(), *getpath(), *pathname;
- X char *newfile, *filename, *unixname(), volume[12], *sep;
- X char *strcpy(), *strcat(), newname[MAX_PATH], *strncat();
- X void exit(), reset_dir(), free();
- X struct directory *dir, *search();
- X
- X if (init(0)) {
- X fprintf(stderr, "mdir: Cannot initialize diskette\n");
- X exit(1);
- X }
- X /* find the volume label */
- X reset_dir();
- X volume[0] = '\0';
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == 0x0)
- X break;
- X /* if not volume label */
- X if (!(dir->attr & 0x08))
- X continue;
- X
- X strncpy(volume, (char *) dir->name, 8);
- X volume[8] = '\0';
- X strncat(volume, (char *) dir->ext, 3);
- X volume[11] = '\0';
- X break;
- X }
- X if (volume[0] == '\0')
- X printf(" Volume in drive has no label\n");
- X else
- X printf(" Volume in drive is %s\n", volume);
- X fargn = 1;
- X wide = 0;
- X /* first argument number */
- X if (argc > 1) {
- X if (!strcmp(argv[1], "-w")) {
- X wide = 1;
- X fargn = 2;
- X }
- X }
- X /* fake an argument */
- X faked = 0;
- X if (argc == fargn) {
- X faked++;
- X argc++;
- X }
- X files = 0;
- X for (i=fargn; i<argc; i++) {
- X if (faked) {
- X filename = getname(".");
- X pathname = getpath(".");
- X }
- X else {
- X filename = getname(argv[i]);
- X pathname = getpath(argv[i]);
- X }
- X /* move to first guess subdirectory */
- X /* required by isdir() */
- X if (subdir(pathname)) {
- X free(filename);
- X free(pathname);
- X continue;
- X }
- X /* is filename really a subdirectory? */
- X if (isdir(filename)) {
- X strcpy(newpath, pathname);
- X if (strcmp(pathname,"/") && strcmp(pathname, "\\")) {
- X if (*pathname != '\0')
- X strcat(newpath, "/");
- X }
- X strcat(newpath, filename);
- X /* move to real subdirectory */
- X if (subdir(newpath)) {
- X free(filename);
- X free(pathname);
- X continue;
- X }
- X strcpy(newname, "*");
- X }
- X else {
- X strcpy(newpath, pathname);
- X strcpy(newname, filename);
- X }
- X
- X if (*filename == '\0')
- X strcpy(newname, "*");
- X
- X if (*newpath == '/' || *newpath == '\\')
- X printf(" Directory for %s\n\n", newpath);
- X else if (!strcmp(newpath, "."))
- X printf(" Directory for %s\n\n", mcwd);
- X else {
- X if (strlen(mcwd) == 1 || !strlen(newpath))
- X sep = "";
- X else
- X sep = "/";
- X printf(" Directory for %s%s%s\n\n", mcwd, sep, newpath);
- X }
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == 0x0)
- X break;
- X /* if erased */
- X if (dir->name[0] == 0xe5)
- X continue;
- X /* if a volume label */
- X if (dir->attr & 0x08)
- X continue;
- X
- X strncpy(name, (char *) dir->name, 8);
- X strncpy(ext, (char *) dir->ext, 3);
- X name[8] = '\0';
- X ext[3] = '\0';
- X
- X newfile = unixname(name, ext);
- X if (!match(newfile, newname)) {
- X free(newfile);
- X continue;
- X }
- X free(newfile);
- X
- X files++;
- X if (wide && files != 1) {
- X if (!((files-1) % 5))
- X putchar('\n');
- X }
- X date = convdate(dir->date[1], dir->date[0]);
- X time = convtime(dir->time[1], dir->time[0]);
- X size = dir->size[2]*0x10000L + dir->size[1]*0x100 + dir->size[0];
- X /* is a subdirectory */
- X if (dir->attr & 0x10) {
- X if (wide)
- X printf("%-9.9s%-6.6s", name, ext);
- X else
- X printf("%8s %3s <DIR> %s %s\n", name, ext, date, time);
- X continue;
- X }
- X if (wide)
- X printf("%-9.9s%-6.6s", name, ext);
- X else
- X printf("%8s %3s %8d %s %s\n", name, ext, size, date, time);
- X }
- X if (argc > 2)
- X putchar('\n');
- X
- X free(filename);
- X free(pathname);
- X }
- X
- X blocks = getfree() * MSECSIZ;
- X if (!files)
- X printf("File \"%s\" not found\n", newname);
- X else
- X printf(" %3d File(s) %6ld bytes free\n", files, blocks);
- X close(fd);
- X exit(0);
- X}
- X
- X/*
- X * Get the amount of free space on the diskette
- X */
- X
- Xint
- Xgetfree()
- X{
- X register int i, total;
- X
- X total = 0;
- X for (i=2; i<num_clus+2; i++) {
- X /* if getfat returns zero */
- X if (!getfat(i))
- X total += clus_size;
- X }
- X return(total);
- X}
- END_OF_FILE
- if test 4882 -ne `wc -c <'mdir.c'`; then
- echo shar: \"'mdir.c'\" unpacked with wrong size!
- fi
- # end of 'mdir.c'
- fi
- if test -f 'mkdfs.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mkdfs.c'\"
- else
- echo shar: Extracting \"'mkdfs.c'\" \(4022 characters\)
- sed "s/^X//" >'mkdfs.c' <<'END_OF_FILE'
- X#ifndef sun
- X /*
- X * FIX ME!
- X * All we need is a convenient way for the user to choose the
- X * DOS layout parameters for the FS, and yet I did not want
- X * to hard code tables for the various drives.
- X * Something like a /etc/dosformat.dat file would be nice
- X * the user can then use mkdfs <drivename>, this involes
- X * table parsing routines etc., not too hard, just unpleasant.
- X */
- X main() {
- X printf("Do not know how to format disks on your system\n";
- X exit(1) ;
- X }
- X#else
- X
- X#include <stdio.h>
- X#include <fcntl.h>
- X#include <errno.h>
- X#include <sys/wait.h>
- X#include <sys/file.h>
- X#include <assert.h>
- X#include "msdos.h"
- X#include "bootblk.h"
- X
- X#define VOLLBL 0x8
- X#define FAT720 0xf9
- X#define FAT1440 0xf0
- Xstatic char floppy[] = "/dev/rfd0c" ;
- Xstatic char disklabel[] = "ANYDSKLABEL" ;
- X
- Xvoid move(), Write(), usage(), formatit() ;
- X
- Xstatic char *progname, buf[MSECSIZ] ;
- X
- Xmain(argc,argv)
- X char **argv;
- X{
- X int c, fd, sec ;
- X int fat_len = 3 ;
- X int fat = FAT720 ;
- X int dir_len = 7 ;
- X int hdflag=0, fflag = 0 ;
- X
- X progname = argv[0] ;
- X
- X while( (c=getopt(argc,argv,"hf")) != EOF ) {
- X switch(c) {
- X case 'f' :
- X fflag++ ;
- X break;
- X case 'h' :
- X hdflag++ ;
- X break;
- X case '?':
- X default:
- X fprintf(stderr,"Unknown option \"%c\"\n",c) ;
- X usage() ;
- X }
- X }
- X
- X if (fflag)
- X formatit(hdflag) ;
- X
- X /* Lets initialize the MSDOS FS */
- X
- X if ( (fd=open(floppy,O_RDWR)) == -1 ) {
- X fprintf(stderr,"%s: open: ",progname) ;
- X perror(floppy) ;
- X exit(1) ;
- X }
- X
- X if ( hdflag ) {
- X dir_len=14 ;
- X fat_len=9 ;
- X fat=FAT1440 ;
- X }
- X
- X bzero(buf,sizeof(buf)) ;
- X bcopy(hdflag?hdboot:ldboot,buf,MSECSIZ) ; /* Create the boot block */
- X Write(fd,buf,MSECSIZ) ; /* Dump the boot block */
- X bzero(buf,sizeof(buf)) ;
- X for( c=0; c < 2 ; ++c ) {
- X buf[0] = fat ;
- X buf[1] = 0xff ;
- X buf[2] = 0xff ;
- X Write(fd,buf,MSECSIZ) ; /* First block of FAT */
- X bzero(buf,3) ;
- X for( sec=fat_len; --sec ; )
- X Write(fd,buf,MSECSIZ) ; /* Rest of FAT */
- X }
- X strcpy(((struct directory *)buf)->name,disklabel) ;
- X ((struct directory *)buf)->attr= VOLLBL ;
- X Write(fd,buf,MSECSIZ) ; /* Root dir */
- X bzero(buf,strlen(disklabel)) ;
- X ((struct directory *)buf)->attr= 0 ;
- X for( ; --dir_len ; )
- X Write(fd,buf,MSECSIZ) ; /* Root dir */
- X}
- X
- Xvoid
- Xmove(fd,sector)
- X int fd, sector ;
- X{
- X if ( lseek(fd,sector*MSECSIZ,L_SET) != sector*MSECSIZ) {
- X fprintf(stderr,"%s: lseek: ",progname) ;
- X perror(floppy) ;
- X exit(1) ;
- X }
- X}
- X
- Xvoid
- XWrite(fd,buf,count)
- X int fd,count ;
- X char * buf ;
- X{
- X if ( write(fd,buf,count) != count ) {
- X fprintf(stderr,"%s: write: ",progname) ;
- X perror(floppy) ;
- X exit(1) ;
- X }
- X}
- X
- Xvoid
- Xusage()
- X{
- X fprintf(stderr,"Usage: %s [-h] [-f]\n",progname) ;
- X fprintf(stderr,"\tBuilds an empty DOS filesystem\n") ;
- X fprintf(stderr,"\t-h: high density\n\t-f: reformat first\n") ;
- X exit(1) ;
- X}
- X
- Xvoid
- Xformatit(hdq)
- X int hdq;
- X{
- X int pid;
- X struct wait w;
- X int retval;
- X
- X if( (pid=fork()) == -1 ) {
- X fprintf(stderr,"%s: ",progname) ;
- X perror("fork") ;
- X exit(1) ;
- X }
- X
- X if ( !pid ) {
- X if ( hdq )
- X execl("/bin/fdformat","fdformat",floppy,0) ;
- X else
- X execl("/bin/fdformat","fdformat","-l",floppy,0) ;
- X
- X fprintf(stderr,"%s: ",progname) ;
- X perror("exec") ;
- X exit(1) ;
- X }
- X
- X while ( (retval=wait4(pid,&w,0,0)) == -1 && errno == EINTR ) ;
- X
- X if (retval == -1) {
- X fprintf(stderr,"%s: ",progname) ;
- X perror("wait4") ;
- X fprintf(stderr,"The format operation may have failed\nTry again\n") ;
- X exit(1) ;
- X }
- X
- X if ( WIFSIGNALED(w) ) {
- X fprintf(stderr,"%s: ",progname) ;
- X psignal(w.w_termsig,"/bin/fdformat") ;
- X if (w.w_coredump)
- X fprintf(stderr,"Core dumped\n") ;
- X exit(1) ;
- X }
- X
- X assert( WIFEXITED(w) ) ; /* If not signalled, must be exited
- X we are not tracing stopped processes */
- X
- X if ( w.w_retcode ) {
- X fprintf(stderr,"%s: /bin/fdformat exited with non-zero exit code %d\n",
- X progname,w.w_retcode) ;
- X exit(1) ;
- X }
- X}
- X#endif
- END_OF_FILE
- if test 4022 -ne `wc -c <'mkdfs.c'`; then
- echo shar: \"'mkdfs.c'\" unpacked with wrong size!
- fi
- # end of 'mkdfs.c'
- fi
- if test -f 'mmd.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mmd.c'\"
- else
- echo shar: Extracting \"'mmd.c'\" \(4058 characters\)
- sed "s/^X//" >'mmd.c' <<'END_OF_FILE'
- X/*
- X * Make a MSDOS sub directory
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X
- Xint fd; /* the file descriptor for the floppy */
- Xint dir_start; /* starting sector for directory */
- Xint dir_len; /* length of directory (in sectors) */
- Xint dir_entries; /* number of directory entries */
- Xint dir_chain[25]; /* chain of sectors in directory */
- Xint clus_size; /* cluster size (in sectors) */
- Xint fat_len; /* length of FAT table (in sectors) */
- Xint num_clus; /* number of available clusters */
- Xunsigned char *fatbuf; /* the File Allocation Table */
- Xchar *mcwd; /* the Current Working Directory */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int entry, slot, fat, dot, fargn, verbose;
- X char *filename, *newfile, *fixname(), *strncpy();
- X char *getpath(), *pathname, tname[9], text[4], *fixed, *unixname();
- X void exit(), putcluster(), writefat(), writedir(), free();
- X struct directory *dir, *search(), *mk_entry();
- X long time(), now;
- X
- X if (init(2)) {
- X fprintf(stderr, "mmd: Cannot initialize diskette\n");
- X exit(1);
- X }
- X
- X fargn = 1;
- X verbose = 0;
- X if (argc > 1) {
- X if (!strcmp(argv[1], "-v")) {
- X fargn = 2;
- X verbose = 1;
- X }
- X }
- X /* only 1 directory ! */
- X if (argc != fargn+1) {
- X fprintf(stderr, "Usage: mmd [-v] msdosdirectory\n");
- X exit(1);
- X }
- X fixed = fixname(argv[fargn], verbose);
- X
- X strncpy(tname, fixed, 8);
- X strncpy(text, fixed+8, 3);
- X tname[8] = '\0';
- X text[3] = '\0';
- X
- X filename = unixname(tname, text);
- X pathname = getpath(argv[fargn]);
- X
- X if (subdir(pathname))
- X exit(1);
- X /* see if exists and get slot */
- X slot = -1;
- X dot = 0;
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == 0x0) {
- X if (slot < 0)
- X slot = entry;
- X break;
- X }
- X /* if erased */
- X if (dir->name[0] == 0xe5) {
- X if (slot < 0)
- X slot = entry;
- X continue;
- X }
- X /* if not a directory */
- X if (!(dir->attr & 0x10))
- X continue;
- X
- X strncpy(tname, (char *) dir->name, 8);
- X strncpy(text, (char *) dir->ext, 3);
- X tname[8] = '\0';
- X text[3] = '\0';
- X
- X newfile = unixname(tname, text);
- X /* save the 'dot' directory info */
- X if (!strcmp(".", newfile))
- X dot = dir->start[1]*0x100 + dir->start[0];
- X
- X if (!strcmp(filename, newfile)) {
- X fprintf(stderr, "mmd: Directory \"%s\" already exists\n", filename);
- X exit(1);
- X }
- X free(newfile);
- X }
- X /* no '.' entry means root directory */
- X if (dot == 0 && slot < 0) {
- X fprintf(stderr, "mmd: No directory slots\n");
- X exit(1);
- X }
- X /* make the directory grow */
- X if (dot && slot < 0) {
- X if (grow(dot)) {
- X fprintf(stderr, "mmd: Disk full\n");
- X exit(1);
- X }
- X /* first slot in 'new' directory */
- X slot = entry;
- X }
- X if ((fat = nextfat(0)) == -1) {
- X fprintf(stderr, "mmd: Disk full\n");
- X exit(1);
- X }
- X /* make directory entry */
- X time(&now);
- X dir = mk_entry(fixed, 0x10, fat, 0L, now);
- X writedir(slot, dir);
- X /* write the cluster */
- X putfat(fat, 0xfff);
- X putcluster(fat, dot);
- X /* write FAT sectors */
- X writefat();
- X close(fd);
- X exit(0);
- X}
- X
- X/*
- X * Write a blank directory 'template' to the cluster starting at 'dot'.
- X */
- X
- Xvoid
- Xputcluster(dot, dot_dot)
- Xint dot, dot_dot;
- X{
- X int buflen, start;
- X static struct directory dirs[32];
- X struct directory *mk_entry();
- X void exit(), perror(), move();
- X long time(), now;
- X
- X start = (dot - 2)*clus_size + dir_start + dir_len;
- X move(start);
- X
- X buflen = clus_size * MSECSIZ;
- X /* make the '.' and '..' entries */
- X time(&now);
- X dirs[0] = *mk_entry(". ", 0x10, dot, 0L, now);
- X dirs[1] = *mk_entry(".. ", 0x10, dot_dot, 0L, now);
- X
- X if (write(fd, (char *) &dirs[0], buflen) != buflen) {
- X perror("putcluster: write");
- X exit(1);
- X }
- X return;
- X}
- X
- X/*
- X * Returns next free cluster or -1 if none are available.
- X */
- X
- Xint
- Xnextfat(last)
- Xint last;
- X{
- X register int i;
- X
- X for (i=last+1; i<num_clus+2; i++) {
- X if (!getfat(i))
- X return(i);
- X }
- X return(-1);
- X}
- END_OF_FILE
- if test 4058 -ne `wc -c <'mmd.c'`; then
- echo shar: \"'mmd.c'\" unpacked with wrong size!
- fi
- # end of 'mmd.c'
- fi
- if test -f 'mrd.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mrd.c'\"
- else
- echo shar: Extracting \"'mrd.c'\" \(3277 characters\)
- sed "s/^X//" >'mrd.c' <<'END_OF_FILE'
- X/*
- X * Delete a MSDOS sub directory
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X
- Xint fd; /* the file descriptor for the floppy */
- Xint dir_start; /* starting sector for directory */
- Xint dir_len; /* length of directory (in sectors) */
- Xint dir_entries; /* number of directory entries */
- Xint dir_chain[25]; /* chain of sectors in directory */
- Xint clus_size; /* cluster size (in sectors) */
- Xint fat_len; /* length of FAT table (in sectors) */
- Xint num_clus; /* number of available clusters */
- Xunsigned char *fatbuf; /* the File Allocation Table */
- Xchar *mcwd; /* the Current Working Directory */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int ismatch, entry, start;
- X char *filename, *newfile, text[4], tname[9], *getname();
- X char *strncpy(), *pathname, *getpath(), *unixname();
- X void exit(), zapit(), writefat(), writedir(), free();
- X struct directory *dir, *search();
- X
- X if (init(2)) {
- X fprintf(stderr, "mrd: Cannot initialize diskette\n");
- X exit(1);
- X }
- X /* only 1 directory ! */
- X if (argc != 2) {
- X fprintf(stderr, "Usage: mrd mdsosdirectory\n");
- X exit(1);
- X }
- X
- X filename = getname(argv[1]);
- X pathname = getpath(argv[1]);
- X if (subdir(pathname))
- X exit(1);
- X
- X ismatch = 0;
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == 0x0)
- X break;
- X /* if erased */
- X if (dir->name[0] == 0xe5)
- X continue;
- X /* if not dir */
- X if (!(dir->attr & 0x10))
- X continue;
- X
- X strncpy(tname, (char *) dir->name, 8);
- X strncpy(text, (char *) dir->ext, 3);
- X tname[8] = '\0';
- X text[3] = '\0';
- X
- X newfile = unixname(tname, text);
- X if (!strcmp(newfile, filename)) {
- X start = dir->start[1]*0x100 + dir->start[0];
- X if (!isempty(start)) {
- X fprintf(stderr, "mrd: Directory \"%s\" is not empty\n", filename);
- X exit(1);
- X }
- X if (!start) {
- X fprintf(stderr, "mrd: Can't remove root directory\n");
- X exit(1);
- X }
- X zapit(start);
- X dir->name[0] = 0xe5;
- X writedir(entry, dir);
- X ismatch = 1;
- X }
- X free(newfile);
- X }
- X if (!ismatch) {
- X fprintf(stderr, "mrd: Directory \"%s\" not found\n", filename);
- X exit(1);
- X }
- X /* update the FAT sectors */
- X writefat();
- X close(fd);
- X exit(0);
- X}
- X
- X/*
- X * See if directory is empty. Returns 1 if empty, 0 if not. Can't use
- X * subdir() and search() as it would clobber the globals.
- X */
- X
- Xint
- Xisempty(fat)
- Xint fat;
- X{
- X register int i;
- X int next, buflen, sector;
- X unsigned char tbuf[CLSTRBUF];
- X void perror(), exit(), move();
- X
- X while (1) {
- X sector = (fat-2)*clus_size + dir_start + dir_len;
- X move(sector);
- X buflen = clus_size * MSECSIZ;
- X if (read(fd, (char *) tbuf, buflen) != buflen) {
- X perror("isempty: read");
- X exit(1);
- X }
- X /* check first character of name */
- X for (i=0; i<MSECSIZ; i+=MDIRSIZ) {
- X if (tbuf[i] == '.')
- X continue;
- X if (tbuf[i] != 0x0 && tbuf[i] != 0xe5)
- X return(0);
- X }
- X /* get next cluster number */
- X next = getfat(fat);
- X if (next == -1) {
- X fprintf(stderr, "isempty: FAT problem\n");
- X exit(1);
- X }
- X /* end of cluster chain */
- X if (next >= 0xff8)
- X break;
- X fat = next;
- X }
- X return(1);
- X}
- END_OF_FILE
- if test 3277 -ne `wc -c <'mrd.c'`; then
- echo shar: \"'mrd.c'\" unpacked with wrong size!
- fi
- # end of 'mrd.c'
- fi
- if test -f 'mread.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mread.c'\"
- else
- echo shar: Extracting \"'mread.c'\" \(6791 characters\)
- sed "s/^X//" >'mread.c' <<'END_OF_FILE'
- X/*
- X * Read (copy) a MSDOS file to Unix
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "msdos.h"
- X
- X#define LOWERCASE
- X
- Xint fd; /* the file descriptor for the floppy */
- Xint dir_start; /* starting sector for directory */
- Xint dir_len; /* length of directory (in sectors) */
- Xint dir_entries; /* number of directory entries */
- Xint dir_chain[25]; /* chain of sectors in directory */
- Xint clus_size; /* cluster size (in sectors) */
- Xint fat_len; /* length of FAT table (in sectors) */
- Xint num_clus; /* number of available clusters */
- Xunsigned char *fatbuf; /* the File Allocation Table */
- Xchar *buf; /* The input buffer */
- Xlong bufsiz; /* It's size */
- Xint maxcontig; /* In clusters */
- Xchar *mcwd; /* the Current Working Directory */
- X
- Xextern union bootblock bb;
- Xlong size;
- Xlong current;
- Xint textmode = 0;
- Xint nowarn = 0;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X extern int optind;
- X extern char *optarg;
- X int fat, i, ismatch, entry, single, c, oops, mod_time;
- X long mod_date, convstamp();
- X char *filename, *newfile, text[4], tname[9], *getname(), *unixname();
- X char *strncpy(), *pathname, *getpath(), *target, tmp[MAX_PATH];
- X char *strcat(), *strcpy();
- X void perror(), exit(), free();
- X struct directory *dir, *search();
- X struct stat stbuf;
- X
- X if (init(0)) {
- X fprintf(stderr, "mread: Cannot initialize diskette\n");
- X exit(1);
- X }
- X /* get command line options */
- X oops = 0;
- X mod_time = 0;
- X while ((c = getopt(argc, argv, "tnm")) != EOF) {
- X switch(c) {
- X case 't':
- X textmode = 1;
- X break;
- X case 'n':
- X nowarn = 1;
- X break;
- X case 'm':
- X mod_time = 1;
- X break;
- X default:
- X oops = 1;
- X break;
- X }
- X }
- X
- X if (oops || (argc - optind) < 2) {
- X fprintf(stderr, "Usage: mread [-tn] msdosfile unixfile\n");
- X fprintf(stderr, " or mread [-tn] msdosfile [msdosfiles...] unixdirectory\n");
- X exit(1);
- X }
- X /* only 1 file to copy... */
- X single = 1;
- X target = argv[argc-1];
- X /* ...unless last arg is a directory */
- X if (!stat(target, &stbuf)) {
- X if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
- X single = 0;
- X }
- X /* too many arguments */
- X if (single && (argc - optind) != 2) {
- X fprintf(stderr,
- X "mread: too many arguments or target dir omitted\n");
- X exit(1);
- X }
- X
- X bufsiz = NSECT(bb.sb) * NTRACK(bb.sb) ;
- X maxcontig = (bufsiz += clus_size - (--bufsiz) % clus_size)/clus_size;
- X
- X if ( (buf = (char *)malloc(bufsiz *= MSECSIZ)) == NULL ) {
- X fprintf(stderr,"Could not allocate input buffer\n");
- X exit(1) ;
- X }
- X
- X for (i=optind; i<argc-1; i++) {
- X filename = getname(argv[i]);
- X pathname = getpath(argv[i]);
- X if (subdir(pathname)) {
- X free(filename);
- X free(pathname);
- X continue;
- X }
- X
- X ismatch = 0;
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == 0x0)
- X break;
- X /* if erased */
- X if (dir->name[0] == 0xe5)
- X continue;
- X /* if dir or volume lable */
- X if ((dir->attr & 0x10) || (dir->attr & 0x08))
- X continue;
- X
- X strncpy(tname, (char *) dir->name, 8);
- X strncpy(text, (char *) dir->ext, 3);
- X tname[8] = '\0';
- X text[3] = '\0';
- X
- X newfile = unixname(tname, text);
- X fat = dir->start[1]*0x100 + dir->start[0];
- X size = dir->size[2]*0x10000L + dir->size[1]*0x100 + dir->size[0];
- X if (mod_time)
- X mod_date = convstamp(dir->time, dir->date);
- X else
- X mod_date = 0L;
- X
- X /* if single file */
- X if (single) {
- X if (!strcmp(newfile, filename)) {
- X readit(fat, target, mod_date);
- X ismatch = 1;
- X break;
- X }
- X }
- X /* if multiple files */
- X else {
- X if (match(newfile, filename)) {
- X printf("Copying %s\n", newfile);
- X strcpy(tmp, target);
- X strcat(tmp, "/");
- X strcat(tmp, newfile);
- X readit(fat, tmp, mod_date);
- X ismatch = 1;
- X }
- X }
- X free(newfile);
- X }
- X if (!ismatch)
- X fprintf(stderr, "mread: File \"%s\" not found\n", filename);
- X free(filename);
- X free(pathname);
- X }
- X close(fd);
- X exit(0);
- X}
- X
- X/*
- X * Decode the FAT chain given the begining FAT entry, open the named Unix
- X * file for write.
- X */
- X
- Xstatic int readpos;
- X
- Xint
- Xreadit(fat, target, mod_date)
- Xint fat;
- Xchar *target;
- Xlong mod_date;
- X{
- X void getclusters() ;
- X char ans[10];
- X void exit();
- X int curfat;
- X FILE *fp;
- X struct stat stbuf;
- X struct utimbuf {
- X time_t actime;
- X time_t modtime;
- X } utbuf;
- X
- X#ifdef LOWERCASE
- X char *c;
- X c = target;
- X while(*c) {
- X if (isupper(*c))
- X *c = tolower(*c);
- X c++;
- X }
- X#endif /* LOWERCASE */
- X
- X if (!nowarn) {
- X if (!access(target, 0)) {
- X while (1) {
- X printf("File \"%s\" exists, overwrite (y/n) ? ", target);
- X gets(ans);
- X if (ans[0] == 'n' || ans[0] == 'N')
- X return;
- X if (ans[0] == 'y' || ans[0] == 'Y')
- X break;
- X }
- X /* sanity checking */
- X if (!stat(target, &stbuf)) {
- X if ((stbuf.st_mode & S_IFREG) != S_IFREG) {
- X fprintf(stderr, "mread: \"%s\" is not a regular file\n", target);
- X return;
- X }
- X }
- X }
- X }
- X
- X if (!(fp = fopen(target, "w"))) {
- X fprintf(stderr, "mread: Can't open \"%s\" for write\n", target);
- X return;
- X }
- X
- X current = 0L;
- X readpos = -1;
- X for(;;) {
- X /*
- X * Find chain of contiguous clusters
- X * curfat -> last in chain + 1
- X */
- X for(curfat=fat;
- X ++curfat < fat + maxcontig &&
- X getfat(curfat-1)==curfat;) ;
- X
- X getclusters(fat, curfat, fp);
- X /* get next cluster number */
- X fat = getfat(--curfat);
- X if (fat == -1) {
- X fprintf(stderr, "mread: FAT problem\n");
- X exit(1);
- X }
- X /* end of cluster chain */
- X if (fat >= 0xff8)
- X break;
- X }
- X if (fclose(fp)) {
- X fprintf(stderr,"Error closing %s\n",target) ;
- X perror("close?") ;
- X exit(1) ;
- X }
- X /* preserve mod times ? */
- X if (mod_date != 0L) {
- X utbuf.actime = mod_date;
- X utbuf.modtime = mod_date;
- X utime(target, &utbuf);
- X }
- X return;
- X}
- X
- X/*
- X * Read the named cluster, write to the Unix file descriptor.
- X */
- X
- Xvoid
- Xgetclusters(start, end, fp)
- XFILE *fp;
- X{
- X register int i;
- X int buflen, blk;
- X void exit(), perror(), move();
- X
- X blk = (start - 2)*clus_size + dir_start + dir_len;
- X if (blk != readpos)
- X move(blk);
- X
- X buflen = (end-start) * clus_size * MSECSIZ;
- X
- X if (read(fd, (char *) buf, buflen) != buflen) {
- X perror("getcluster: read");
- X exit(1);
- X }
- X readpos = blk + (end-start)*clus_size;
- X /* stop at size not EOF marker */
- X if (textmode) {
- X for (i=0; i<buflen; i++) {
- X current++;
- X if (current > size)
- X break;
- X if ( buf[i] == '\r')
- X continue;
- X if ( current == size && buf[i] == 0x1a)
- X continue;
- X putc((char) buf[i], fp);
- X }
- X }
- X else {
- X buflen = (size > buflen) ? buflen : size;
- X if (fwrite(buf,buflen,1,fp)!=1) {
- X perror("getclusters: fwrite") ;
- X exit(1) ;
- X }
- X size -= buflen ;
- X }
- X
- X return;
- X}
- END_OF_FILE
- if test 6791 -ne `wc -c <'mread.c'`; then
- echo shar: \"'mread.c'\" unpacked with wrong size!
- fi
- # end of 'mread.c'
- fi
- if test -f 'mren.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mren.c'\"
- else
- echo shar: Extracting \"'mren.c'\" \(3153 characters\)
- sed "s/^X//" >'mren.c' <<'END_OF_FILE'
- X/*
- X * Rename an existing MSDOS file
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X
- Xint fd; /* the file descriptor for the floppy */
- Xint dir_start; /* starting sector for directory */
- Xint dir_len; /* length of directory (in sectors) */
- Xint dir_entries; /* number of directory entries */
- Xint dir_chain[25]; /* chain of sectors in directory */
- Xint clus_size; /* cluster size (in sectors) */
- Xint fat_len; /* length of FAT table (in sectors) */
- Xint num_clus; /* number of available clusters */
- Xunsigned char *fatbuf; /* the File Allocation Table */
- Xchar *mcwd; /* the Current Working Directory */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int entry, ismatch, nogo, fargn, verbose, got_it;
- X char *filename, *newfile, *fixname(), *strncpy(), *unixname();
- X char *getpath(), *pathname, tname[9], text[4], *getname(), *target;
- X char *new, ans[10], *temp, *strcpy();
- X void exit(), writedir(), free();
- X struct directory *dir, *search();
- X
- X if (init(2)) {
- X fprintf(stderr, "mren: Cannot initialize diskette\n");
- X exit(1);
- X }
- X fargn = 1;
- X verbose = 0;
- X if (argc > 1) {
- X if (!strcmp(argv[1], "-v")) {
- X fargn = 2;
- X verbose = 1;
- X }
- X }
- X if (argc != fargn+2) {
- X fprintf(stderr, "Usage: mren [-v] sourcefile targetfile\n");
- X exit(1);
- X }
- X filename = getname(argv[fargn]);
- X pathname = getpath(argv[fargn]);
- X if (subdir(pathname))
- X exit(1);
- X
- X temp = getname(argv[fargn+1]);
- X target = fixname(argv[fargn+1], verbose);
- X
- X strncpy(tname, target, 8);
- X strncpy(text, target+8, 3);
- X tname[8] = '\0';
- X text[3] = '\0';
- X
- X new = unixname(tname, text);
- X nogo = 0;
- X /* the name supplied may be altered */
- X if (strcmp(temp, new) && verbose) {
- X while (!nogo) {
- X printf("Do you accept \"%s\" as the new file name (y/n) ? ", new);
- X gets(ans);
- X if (ans[0] == 'y' || ans[0] == 'Y')
- X break;
- X if (ans[0] == 'n' || ans[0] == 'N')
- X nogo = 1;
- X }
- X }
- X if (nogo)
- X exit(0);
- X /* see if exists and do it */
- X ismatch = 0;
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == 0x0)
- X break;
- X /* if erased */
- X if (dir->name[0] == 0xe5)
- X continue;
- X /* if volume label */
- X if (dir->attr == 0x08)
- X continue;
- X /* you may rename a directory */
- X strncpy(tname, (char *) dir->name, 8);
- X strncpy(text, (char *) dir->ext, 3);
- X tname[8] = '\0';
- X text[3] = '\0';
- X
- X newfile = unixname(tname, text);
- X
- X /* if the new name already exists */
- X if (!strcmp(new, newfile)) {
- X fprintf(stderr, "mren: File \"%s\" already exists\n", new);
- X exit(1);
- X }
- X /* if the old name exists */
- X if (!strcmp(filename, newfile)) {
- X ismatch = 1;
- X got_it = entry;
- X }
- X free(newfile);
- X }
- X if (!ismatch) {
- X fprintf(stderr, "mren: File \"%s\" not found\n", filename);
- X exit(1);
- X }
- X /* so go ahead and do it */
- X dir = search(got_it);
- X strncpy((char *) dir->name, target, 8);
- X strncpy((char *) dir->ext, target+8, 3);
- X writedir(got_it, dir);
- X
- X close(fd);
- X exit(0);
- X}
- END_OF_FILE
- if test 3153 -ne `wc -c <'mren.c'`; then
- echo shar: \"'mren.c'\" unpacked with wrong size!
- fi
- # end of 'mren.c'
- fi
- if test -f 'mtype.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mtype.c'\"
- else
- echo shar: Extracting \"'mtype.c'\" \(3748 characters\)
- sed "s/^X//" >'mtype.c' <<'END_OF_FILE'
- X/*
- X * Display contents of a MSDOS file
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X
- Xint fd; /* the file descriptor for the floppy */
- Xint dir_start; /* starting sector for directory */
- Xint dir_len; /* length of directory (in sectors) */
- Xint dir_entries; /* number of directory entries */
- Xint dir_chain[25]; /* chain of sectors in directory */
- Xint clus_size; /* cluster size (in sectors) */
- Xint fat_len; /* length of FAT table (in sectors) */
- Xint num_clus; /* number of available clusters */
- Xunsigned char *fatbuf; /* the File Allocation Table */
- Xchar *mcwd; /* the Current Working Directory */
- X
- Xlong size;
- Xlong current;
- Xint stripmode = 0;
- Xint textmode = 0;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X extern int optind;
- X extern char *optarg;
- X int fat, i, ismatch, entry, c, oops;
- X char *filename, *newfile, text[4], tname[9], *getname(), *unixname();
- X char *strncpy(), *pathname, *getpath();
- X void exit(), readit(), free();
- X struct directory *dir, *search();
- X
- X if (init(0)) {
- X fprintf(stderr, "mtype: Cannot initialize diskette\n");
- X exit(1);
- X }
- X /* get command line options */
- X oops = 0;
- X while ((c = getopt(argc, argv, "st")) != EOF) {
- X switch(c) {
- X case 's':
- X stripmode = 1;
- X break;
- X case 't':
- X textmode = 1;
- X break;
- X default:
- X oops = 1;
- X break;
- X }
- X }
- X
- X if (oops || (argc - optind) < 1) {
- X fprintf(stderr, "Usage: mtype [-st] msdosfile [msdosfiles...]\n");
- X exit(1);
- X }
- X
- X for (i=optind; i<argc; i++) {
- X filename = getname(argv[i]);
- X pathname = getpath(argv[i]);
- X if (subdir(pathname)) {
- X free(filename);
- X free(pathname);
- X continue;
- X }
- X ismatch = 0;
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == 0x0)
- X break;
- X /* if erased */
- X if (dir->name[0] == 0xe5)
- X continue;
- X /* if dir or volume label */
- X if ((dir->attr & 0x10) || (dir->attr & 0x08))
- X continue;
- X
- X strncpy(tname, (char *) dir->name, 8);
- X strncpy(text, (char *) dir->ext, 3);
- X tname[8] = '\0';
- X text[3] = '\0';
- X
- X newfile = unixname(tname, text);
- X /* see it if matches the pattern */
- X if (match(newfile, filename)) {
- X fat = dir->start[1]*0x100 + dir->start[0];
- X size = dir->size[2]*0x10000L + dir->size[1]*0x100 + dir->size[0];
- X readit(fat);
- X ismatch = 1;
- X }
- X free(newfile);
- X }
- X if (!ismatch)
- X fprintf(stderr, "mtype: File \"%s\" not found\n", filename);
- X free(filename);
- X free(pathname);
- X }
- X close(fd);
- X exit(0);
- X}
- X
- X/*
- X * Decode the FAT chain given the begining FAT entry.
- X */
- X
- Xvoid
- Xreadit(fat)
- Xint fat;
- X{
- X void getcluster();
- X
- X current = 0L;
- X while (1) {
- X getcluster(fat);
- X /* get next cluster number */
- X fat = getfat(fat);
- X if (fat == -1) {
- X fprintf(stderr, "mtype: FAT problem\n");
- X exit(1);
- X }
- X /* end of cluster chain */
- X if (fat >= 0xff8)
- X break;
- X }
- X return;
- X}
- X
- X/*
- X * Read the named cluster, output to the stdout.
- X */
- X
- Xvoid
- Xgetcluster(num)
- Xint num;
- X{
- X register int i;
- X int buflen, start;
- X unsigned char buf[CLSTRBUF];
- X void exit(), perror(), move();
- X
- X start = (num - 2)*clus_size + dir_start + dir_len;
- X move(start);
- X
- X buflen = clus_size * MSECSIZ;
- X if (read(fd, (char *) buf, buflen) != buflen) {
- X perror("getcluster: read");
- X exit(1);
- X }
- X /* stop at size not EOF marker */
- X for (i=0; i<buflen; i++) {
- X current++;
- X if (current > size)
- X break;
- X if (textmode && buf[i] == '\r')
- X continue;
- X if (textmode && current == size && buf[i] == 0x1a)
- X continue;
- X if (stripmode)
- X putchar(buf[i] & 0x7f);
- X else
- X putchar(buf[i]);
- X }
- X return;
- X}
- END_OF_FILE
- if test 3748 -ne `wc -c <'mtype.c'`; then
- echo shar: \"'mtype.c'\" unpacked with wrong size!
- fi
- # end of 'mtype.c'
- fi
- if test -f 'subdir.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'subdir.c'\"
- else
- echo shar: Extracting \"'subdir.c'\" \(3775 characters\)
- sed "s/^X//" >'subdir.c' <<'END_OF_FILE'
- X/*
- X * subdir(), getdir(), get_chain(), reset_dir()
- X */
- X
- X#include <stdio.h>
- X#include "msdos.h"
- X
- Xextern int dir_chain[25], dir_start, dir_len, dir_entries, clus_size;
- Xextern char *mcwd;
- Xstatic char lastpath[MAX_PATH];
- X
- X/*
- X * Parse the path names of a sub directory. Both '/' and '\' are
- X * valid separators. However, the use of '\' will force the operator
- X * to use quotes in the command line to protect '\' from the shell.
- X * Returns 1 on error. Attempts to optimize by remembering the last
- X * path it parsed
- X */
- X
- Xint
- Xsubdir(name)
- Xchar *name;
- X{
- X char *s, *tmp, tbuf[MAX_PATH], *path, *strcpy(), *strcat();
- X int code;
- X void reset_dir();
- X /* if full pathname */
- X if (*name == '/' || *name == '\\')
- X strcpy(tbuf, name);
- X /* if relative to MCWD */
- X else {
- X if (!strlen(name))
- X strcpy(tbuf, mcwd);
- X else {
- X strcpy(tbuf, mcwd);
- X strcat(tbuf, "/");
- X strcat(tbuf, name);
- X }
- X }
- X /* if paths are same, do nothing */
- X if (!strcmp(tbuf, lastpath))
- X return(0);
- X /* not recursive, start at root */
- X reset_dir();
- X strcpy(lastpath, tbuf);
- X /* zap the leading separator */
- X tmp = tbuf;
- X if (*tmp == '\\' || *tmp == '/')
- X tmp++;
- X for (s = tmp; *s; ++s) {
- X if (*s == '\\' || *s == '/') {
- X path = tmp;
- X *s = '\0';
- X if (getdir(path))
- X return(1);
- X tmp = s+1;
- X }
- X }
- X code = getdir(tmp);
- X return(code);
- X}
- X
- X/*
- X * Find the directory and get the starting cluster. A null directory
- X * is ok. Returns a 1 on error.
- X */
- X
- Xint
- Xgetdir(path)
- Xchar *path;
- X{
- X int entry, start;
- X char *newname, *unixname(), *strncpy(), name[9], ext[4];
- X struct directory *dir, *search();
- X void reset_dir(), free();
- X /* nothing required */
- X if (*path == '\0')
- X return(0);
- X
- X for (entry=0; entry<dir_entries; entry++) {
- X dir = search(entry);
- X /* if empty */
- X if (dir->name[0] == 0x0)
- X break;
- X /* if erased */
- X if (dir->name[0] == 0xe5)
- X continue;
- X /* skip if not a directory */
- X if (!(dir->attr & 0x10))
- X continue;
- X
- X strncpy(name, (char *) dir->name, 8);
- X strncpy(ext, (char *) dir->ext, 3);
- X name[8] = '\0';
- X ext[3] = '\0';
- X
- X newname = unixname(name, ext);
- X if (!strcmp(newname, path)) {
- X start = dir->start[1]*0x100 + dir->start[0];
- X /* if '..' pointing to root */
- X if (!start && !strcmp(path, "..")) {
- X reset_dir();
- X return(0);
- X }
- X /* fill in the directory chain */
- X dir_entries = get_chain(start) * 16;
- X return(0);
- X }
- X free(newname);
- X }
- X /* if '.' or '..', must be root */
- X if (!strcmp(path, ".") || !strcmp(path, "..")) {
- X reset_dir();
- X return(0);
- X }
- X fprintf(stderr, "Path component \"%s\" is not a directory\n", path);
- X return(1);
- X}
- X
- X/*
- X * Fill in the global variable dir_chain. Argument is the starting
- X * cluster number. Info, in this variable is used by search() to
- X * scan a directory. An arbitrary limit of 25 sectors is placed, this
- X * equates to 400 entries. Returns the number of sectors in the chain.
- X */
- X
- Xint
- Xget_chain(num) /* fill the directory chain */
- Xint num;
- X{
- X int i, next;
- X void exit();
- X
- X i = 0;
- X while (1) {
- X dir_chain[i] = (num - 2)*clus_size + dir_start + dir_len;
- X /* sectors, not clusters! */
- X if (clus_size == 2) {
- X dir_chain[i+1] = dir_chain[i] + 1;
- X i++;
- X }
- X i++;
- X if (i >= 25) {
- X fprintf(stderr, "get_chain: directory too large\n");
- X exit(1);
- X }
- X /* get next cluster number */
- X next = getfat(num);
- X if (next == -1) {
- X fprintf(stderr, "get_chain: FAT problem\n");
- X exit(1);
- X }
- X /* end of cluster chain */
- X if (next >= 0xff8) {
- X break;
- X }
- X num = next;
- X }
- X return(i);
- X}
- X
- X/*
- X * Reset the global variable dir_chain to the root directory.
- X */
- X
- Xvoid
- Xreset_dir()
- X{
- X register int i;
- X
- X for (i=0; i<dir_len; i++)
- X dir_chain[i] = dir_start + i;
- X dir_entries = dir_len * 16;
- X /* disable subdir() optimization */
- X lastpath[0] = '\0';
- X return;
- X}
- END_OF_FILE
- if test 3775 -ne `wc -c <'subdir.c'`; then
- echo shar: \"'subdir.c'\" unpacked with wrong size!
- fi
- # end of 'subdir.c'
- fi
- echo shar: End of archive 2 \(of 3\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- Viktor Dukhovni <viktor@math.princeton.edu> : ARPA
- <...!uunet!princeton!math!viktor> : UUCP
- Fine Hall, Washington Rd., Princeton, NJ 08544 : US-Post
- +1-(609)-258-5792 : VOICE
-
-